<?php
namespace app\api\service;

use GuzzleHttp\Client;
use app\lib\exception\WeChatException;
use app\api\model\User as UserModel;
use app\lib\exception\TokenException;
use think\Exception;
use app\lib\enum\ScopeEnum;

class UserToken extends Token{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    function __construct($code){
        $this->code = $code;
        $this->wxAppID = config('wx.appid');
        $this->wxAppSecret = config('wx.secret');
        $this->wxLoginUrl = sprintf(config('wx.login_url'), $this->wxAppID, $this->wxAppSecret, $this->code);
    }

    public function get(){
        $result = curl_get($this->wxLoginUrl);
        $wxResult = json_decode($result, true);
        if(empty($wxResult)){
            throw new Exception('获取session_key及openID时异常，微信内部错误');
        }else{
            $loginFail = array_key_exists('errcode', $wxResult);
            if($loginFail){
                $this->progressLoginError($wxResult);
            }else{
                //设置令牌
                return $this->grantToken($wxResult);
            }
        }
    }

    //生成令牌
    private function grantToken($wxResult){
        //拿到openid
        //数据库看一下，这个openid是否已经存在，如果存在则不处理，不存在新增一条记录
        //准备缓存数据，写入缓存, 把令牌返回到客户端
        //key：令牌，  value: wxResult uid scope权限
        $openid = $wxResult['openid'];
        $user = UserModel::getByOpenID($openid);
        if($user){
            $uid = $user->id;
        }else{
            $uid = UserModel::addUser($openid);
        };
        $cacheValue = $this->prepareCacheValue($wxResult, $uid);
        $token = $this->saveCache($cacheValue);
        return $token;
    }

    //准备缓存数据
    private function prepareCacheValue($wxResult, $uid){
        $cacheValue = $wxResult;
        $cacheValue['uid'] = $uid;
        $cacheValue['scope'] = ScopeEnum::User;  //权限
        return $cacheValue;
    }

    //写入缓存
    private function saveCache($cacheValue){
        //生成令牌
        $key = self::generateToken();
        $value = json_encode($cacheValue);
        $expire_in = config('setting.token_expire_in');
        //写入缓存，默认使用文件缓存
        $request = cache($key, $value, $expire_in);
        if(!$request){
            throw new TokenException([
                'msg' => '服务器缓存异常',
                'errorCode' => 10005
            ]);
        };
        return $key;
    }

    private function progressLoginError($wxResult){
        throw new WeChatException();
    }
}

?>